package it.free.maya.worddistinct;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.log4j.Logger;

/**
 * Load a solr synonyms file, using its content to make synonyms substitution from 
 * a list of loaded words
 * @author Stefano Falconetti
 */
public class WordsSynonymsFilter {

	private File synonymsFile = null;
	private HashMap<String, Word> wordsList = null;
	
	private static Logger logger = Logger.getLogger(WordsSynonymsFilter.class);
	
	private static final String ARROW = "=>";
	private static final String COMMA = ",";
	
	/**
	 * Class builder, note that this class modify the copy of the words list passed
	 * @param stopWords is the file of solr stop words
	 */
	public WordsSynonymsFilter(File stopWords){
		this.synonymsFile = stopWords;
	}
	
	/**
	 * Load the synonyms
	 * @return the list of synonyms per word
	 */
	private void loadSynonyms() throws Exception {
		
		if( (this.synonymsFile == null) ||
			(!this.synonymsFile.exists()) ){
			throw new Exception("Unable to load synonyms file, aborting");
		}
		
		BufferedReader bufferedReader = null;
		
		String oneLine = "";
		List<String> synonymsListToBeReplaced = null;
		StringTokenizer commaTokenizer = null;
		StringTokenizer arrowTokenizer = null;
		
		String tmpArrowLeftToken = null;
		String tmpArrowRightToken = null;
		
		this.wordsList = new HashMap<String, Word>();
		
		Word tmpWord = null;
		
		try{
			bufferedReader = new BufferedReader(new FileReader(this.synonymsFile));
		    while(oneLine != null){
		    	  oneLine = bufferedReader.readLine();
		    	  if(oneLine != null){
		    		 if(!oneLine.startsWith("#")){
		    			
		    			 if(oneLine.indexOf(WordsSynonymsFilter.ARROW) == -1){
		    				continue; 
		    			 }
		    			 //A line in synonyms.txt is like this: token1, token2 => replacement
		    			 logger.info("New line found in synonyms file: [" + oneLine + "]");
		    			 synonymsListToBeReplaced = new ArrayList<String>(); 
		    			 arrowTokenizer = new StringTokenizer(oneLine, WordsSynonymsFilter.ARROW);
		    			 tmpArrowLeftToken = arrowTokenizer.nextToken().trim();  //token1, token2 
		    			 tmpArrowRightToken = arrowTokenizer.nextToken().trim(); //replacement
		    			 
		    			 //This if-else builds the list of words to be replaced
		    			 if(tmpArrowLeftToken.indexOf(WordsSynonymsFilter.COMMA) != -1){
		    				commaTokenizer = new StringTokenizer(tmpArrowLeftToken, WordsSynonymsFilter.COMMA);
		    				while(commaTokenizer.hasMoreTokens()){
		    					  synonymsListToBeReplaced.add(commaTokenizer.nextToken().trim());
		    				}
		    			 }else{
		    				   tmpArrowLeftToken = tmpArrowLeftToken.trim();
		    				   synonymsListToBeReplaced.add(tmpArrowLeftToken);
		    			 }
		    			 //Looking for synonymsListToBeReplaced, to be all replaced with tmpArrowRightToken
		    			 
		    			 logger.info("Storing synonyms [" + synonymsListToBeReplaced + "], to be all replaced by [" + tmpArrowRightToken + "] in words list");
		    			 
		    			 tmpWord = new Word();
		    			 tmpWord.setSynonyms(synonymsListToBeReplaced);
		    			 tmpWord.setWord(tmpArrowRightToken);
		
		    			 this.wordsList.put(tmpArrowRightToken, tmpWord);
		    		 }
		    	  }
		    }
		}finally{
			     if(bufferedReader != null){
			        bufferedReader.close();
			     }
		}
	}
	
	/**
	 * Activate the stop words filtering process, to act over a map passed in the constructor
	 * @return the class input words, cleaned out of stop words found in the file whose descriptor has been passed.
	 * @throws Exception
	 */
	public void process() throws Exception {
		this.loadSynonyms();
	}
	
	/**
	 * Get the list of synonyms produced by the loading procedure
	 * @return the list
	 */
	public HashMap<String, Word> getSynonyms(){
		return this.wordsList;
	}
	
	/**
	 * Entry point for testing purposes
	 * @param args
	 */
	public static final void main(String[] args){
		
		String strange = "Ferrari - Il Mito (Dvd) dd dd dd";
		
		WordsSynonymsFilter wordsSynonymsFilter = new WordsSynonymsFilter(new File("/home/c012426/dev/maya/apache-solr-1.4.0_core_search/conf/synonyms.txt"));
		try {
			wordsSynonymsFilter.process();
		} catch (Exception exc) {
			// TODO Auto-generated catch block
			exc.printStackTrace();
		}
	}
}
